#ifndef TCPSERVER_H
#define TCPSERVER_H

// 监听客户端的请求，并进行广播

#include <QTcpServer>
#include <QTimer>
#include <utility>
#include <tcpsocket.h>

class TcpServer : public QTcpServer
{
    Q_OBJECT
    friend class DrawServer;

public:
    // 构造函数的参数有端口号
    explicit TcpServer(QObject *parent = nullptr, int port = 50112);
    ~TcpServer();
    // 切换画家
    void takeTurnsToDraw();
    // 等待一段时间
    static void callDelay(int);
    /*
     * 消息处理函数，用参数定义消息类型，用分号切分消息内容
     * 用户名：1;username
     * 颜色、粗细和坐标：2;color;width;x;y;x;y;
     * 用户发言：3;username;word;
     * 清屏：4;
     * 发给画家的词语：5;word;
     * 切换画家：6;
     * 剩余时间：7;time;
     * 弃权消息：8;username;
     * 游戏结果：9;username;word;
     * 用户下线：0;number;username;   number表示用户在列表中的编号
     */
    // 清屏和取消画家资格
    void sendMsg(int type);
    // 剩余时间
    void sendMsg(int type, int time);
    // 题目和弃权
    void sendMsg(int type, const QString& word);
    // 游戏结果
    void sendMsg(int type, const QString& name, const QString& word);
    // 用户下线
    void sendMsg(int type, int number, const QString& name);

    // 设定当前回合的词语
    void setCurrentWord(QString word)
    {
        currentWord = std::move(word);
    }
    // 获取当前回合的词语
    QString getCurrentWord()
    {
        return currentWord;
    }
    // 判断用户发送的回答是否正确
    void handleResult(const QByteArray&, int);

protected:
    // 接收客户端连接
    void incomingConnection(qintptr);

private:
    // 题目
    QString currentWord;
    // 各个客户端的套接字描述符列表
    QList<TcpSocket *> clientSocketList;
    // 用户名列表
    QList<QString> userNameList;
    // 当前画家的序列号
    int currentPainter{};
    // 词语列表
    QList<QString> wordList;
    // 游戏是否已经开始
    bool isGamePlaying;
    // 作答时间计时器，该计时器结束时本回合结束
    QTimer *outerTimer;
    // 剩余作答时间计时器，该计时器结束时通知服务端更新剩余作答时间
    QTimer *innerTimer;
    // 作答时长
    int totalTime;

signals:
    // 用户发消息的信号
    void singalNewMsg(QByteArray);
    // 用户断开连接的信号
    void signalClientDisconnected(int);
    // 用户上线的信号
    void signalNewClient(QString, int);
    // 允许服务端开始游戏的信号
    void signalAllowToPlay(bool);

private slots:
    // 接收消息的槽函数
    void msgReceivedSlot(const QByteArray&, int);
    // 用户断开连接的槽函数
    void clientDisconnectedSlot(int);
    // 新用户连接的槽函数
    void newClientSlot(const QString&, int);
    // 开始游戏
    void startGameSlot();
    // 设定计时器
    void outerTimerSlot();
    void innerTimerSlot();
    // 停止作画
    void stopDrawingSlot();
    // 在线用户数量满足要求
    void allowToPlaySlot(bool);
};
#endif // TCPSERVER_H
